﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SharpSoft.WPF.Controls
{
    public class Tabs : TabControl
    {
        static Tabs()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Tabs), new FrameworkPropertyMetadata(typeof(Tabs)));

        }
        public Tabs()
        {
            TabItemClose_Command = new TabItemCloseCommand(this);

        }
        public TabItemCloseCommand TabItemClose_Command
        {
            get { return (TabItemCloseCommand)GetValue(TabItemClose_CommandProperty); }
            private set { SetValue(TabItemClose_CommandPropertyKey, value); }
        }
        private static DependencyPropertyKey TabItemClose_CommandPropertyKey = DependencyProperty.RegisterReadOnly("TabItemClose_Command", typeof(TabItemCloseCommand), typeof(Tabs), new PropertyMetadata(default(TabItemCloseCommand)));
        public static DependencyProperty TabItemClose_CommandProperty = TabItemClose_CommandPropertyKey.DependencyProperty;

        protected override void OnSelectionChanged(SelectionChangedEventArgs e)
        {
            base.OnSelectionChanged(e);
            this.TabItemClose_Command.NotifyChange();
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);
            this.TabItemClose_Command.NotifyChange();
        }
    }

    public class TabItemCloseCommand : ICommand
    {

        public TabItemCloseCommand(Tabs _tabs)
        {
            tabs = _tabs;
        }
        private Tabs tabs;

        public event EventHandler CanExecuteChanged;

        public void NotifyChange()
        {
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }

        public bool CanExecute(object parameter)
        {
            if (parameter is string str)
            {
                switch (str)
                {
                    case "current":
                        return (tabs.SelectedItem is CloseableTabItem cti && cti.CanClose);
                    case "other":
                        return tabs.SelectedIndex >= 0 && tabs.Items.Count > 1;
                    case "all":
                        return tabs.Items.Count > 1;
                    default:
                        break;
                }
            }
            return false;
        }

        public void Execute(object parameter)
        {
            if (parameter is string str)
            {
                List<CloseableTabItem> removeList = new List<CloseableTabItem>();
                switch (str)
                {
                    case "current":
                        {
                            if (tabs.SelectedItem is CloseableTabItem cti)
                            {
                                cti.Close();
                            }
                        }
                        break;
                    case "other":
                        {
                            if (tabs.SelectedItem is CloseableTabItem cti)
                            {
                                foreach (var item in tabs.Items)
                                {
                                    if (item is CloseableTabItem cti1 && cti1 != cti)
                                    {
                                        removeList.Add(cti1);
                                    }
                                }

                            }
                        }
                        break;
                    case "all":
                        {
                            foreach (var item in tabs.Items)
                            {
                                if (item is CloseableTabItem cti1)
                                {
                                    removeList.Add(cti1);
                                }
                            }
                        }
                        break;
                    default:
                        break;
                }
                foreach (var item in removeList)
                {
                    item.Close();
                }
            }
        }
    }
}
